class MathUtils {
    static dir: egret.Point;
    public constructor() {
        MathUtils.dir = egret.Point.create(0, 0);
    }

    public static getPointSideOfLine(ptstart: egret.Point, ptend: egret.Point, pt: egret.Point): number {
        let side = ptend.x;// (((ptstart.y – ptend.y) * pt.x) + ((ptend.x – ptstart.x) * pt.y) + (ptstart.x * ptend.y) – (ptend.x * ptstart.y));
        return side;
    }

    public static getDistanceBetweenPoints(ptstart: egret.Point, ptend: egret.Point): number {
        let dis = egret.Point.distance(ptstart, ptend);
        return dis;
    }

    public static getRandomDirInRange(offsetAngle1: number, offsetAngle2: number): egret.Point {
        if (MathUtils.dir == undefined) {
            MathUtils.dir = egret.Point.create(0, 0);
        }
        var angle = MathUtils.RandomRange(offsetAngle1, offsetAngle2) * Math.PI / 180;

        this.dir.setTo(Math.sin(angle), Math.cos(angle));
        this.dir.normalize(1);
        return this.dir;
    }

    public static getRandomDir(): egret.Point {
        if (MathUtils.dir == undefined) {
            MathUtils.dir = egret.Point.create(0, 0);
        }
        var angle = Math.random() * 360 * Math.PI / 180;
        this.dir.setTo(Math.sin(angle), Math.cos(angle));
        this.dir.normalize(1);
        return this.dir;
    }

    public static calculateNextPoint(pos: egret.Point, dir: egret.Point, speed: number) {
        dir.normalize(speed);
        pos = pos.add(dir);
        return { x: pos.x, y: pos.y };
    } 

    private static NextPointdir =new egret.Point(0,0);
    private static NextPointpos=new egret.Point(0,0);
    public static calculateNextPointEx(curX: number, curY: number, dirX: number, dirY: number, speed: number, output: boolean) {


       this.NextPointdir.setTo(dirX, dirY);
       this.NextPointpos.setTo(curX, curX);
     

         this.NextPointdir.normalize(speed);
        
        //     if(output)
        //   console.log( "原来的位置" + curX +"|"+curY + "移动方向" + dirX +"|"+dirY + "新位置" +pos.x +"|" + pos.y );
        return { x:  this.NextPointdir.x+ this.NextPointpos.x, y: this.NextPointdir.y+ this.NextPointpos.y };
    }

    public static RandomRange(down: number, up: number): number {
        return down + Math.random() * (up - down);
    }

    static ZERO: number = 1e-9;//误差，小于这个就当作0
    static double_equals(a: number, b: number): boolean {
        return Math.abs(a - b) < MathUtils.ZERO;
    }

    static distance_sqr(x1: number, y1: number, x2: number, y2: number): number {
        return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    }
    static distance(x1: number, y1: number, x2: number, y2: number): number {
        return Math.sqrt(this.distance_sqr(x1, y1, x2, y2));
    }

    static getAngle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number): number {

        let dsx = x1 - x0;
        let dsy = y1 - y0;
        let dex = x2 - x0;
        let dey = y2 - y0;

        let cosfi = dsx * dex + dsy * dey;
        let norm = (dsx * dsx + dsy * dsy) * (dex * dex + dey * dey);
        cosfi /= Math.sqrt(norm);

        if (cosfi >= 1.0) return 0;
        if (cosfi <= -1.0) return Math.PI;
        let fi = Math.acos(cosfi);

        return 180 * fi / Math.PI;
    }

    public static getAngleEx(x1: number, y1: number, x2: number, y2: number): number {
        //两点的x、y值
        let x = x2 - x1;
        let y = y2 - y1;
        let z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        //斜边长度
        let cos = x / z;
        let radian = Math.acos(cos);
        //求出弧度
        let angle = 180 / (Math.PI / radian);
        //用弧度算出角度       
        if (y < 0) {
            angle = -angle;
        }
        else if ((y == 0) && (x < 0)) {
            angle = 180;
        }
        return angle;
    }

    public static Dot(x1: number, y1: number, x2: number, y2: number): boolean {
        let ret = x1 * x2 + y1 * y2;
        if (ret >= -0) {
            return true;
        }
        return false;
    }
    public static getOnePointOnLine(x1: number, y1: number, x2: number, y2: number) {
        let pt = { x: 0, y: 0 };
        let radom = Math.random();
        pt.x = x1 + (x2 - x1) * radom;
        pt.y = y1 + (y2 - y1) * radom;
        return pt;
    }

    public static getOnePointOnLineAt(x1: number, y1: number, x2: number, y2: number, rate: number) {
        let pt = { x: 0, y: 0 };
        let radom = Math.random();
        pt.x = x1 + (x2 - x1) * rate;
        pt.y = y1 + (y2 - y1) * rate;
        return pt;
    }
    public static getCircleInsect(x1: number, y1: number, r1: number, x2: number, y2: number, r2: number) {

        let insectInfo = { insectType: 0, angle: 0, arg1: 0, arg2: 0 };  //insectType 0 -任意移动  1-向对方点移动 2-限定角度移动， -1，没办法了怎么移动都没用
        /*&   var shp:egret.Shape = new egret.Shape();
            shp.graphics.lineStyle( 2, 0x00ff00 );
            shp.graphics.moveTo( x1,y1 );
            shp.graphics.lineTo( x2,y2 );
            shp.graphics.drawCircle(x1,y1,r1);
            shp.graphics.drawCircle(x2,y2,r2);*/
        if (MathUtils.double_equals(x1, x2)
            && MathUtils.double_equals(y1, y2)
            && MathUtils.double_equals(r1, r2)) {
            //  console.log("随便跑");
            insectInfo.insectType = 0;
            return insectInfo;
        }

        //无交点  
        let d = this.distance(x1, y1, x2, y2);
        // console.log("跑, 距离" + d);
        if (d > r1 + r2) {
            // console.log("算不出来焦点了");
            insectInfo.insectType = -1;
            return insectInfo;
        }

        if (d < Math.abs(r1 - r2)) {
            // console.log("第一个人的位置" + x1 + "|" + y1 + "移动半径" + r1 + "第二个人的位置" + x2 + "|" + y2 + "线长" + r2);
            //  console.log("随便跑, 距离" + d + "距离差" + (r1 - r2));
            insectInfo.insectType = 0;
            return insectInfo;
        }

        let a = 2.0 * r1 * (x1 - x2);
        let b = 2.0 * r1 * (y1 - y2);
        let c = r2 * r2 - r1 * r1 - this.distance_sqr(x1, y1, x2, y2);
        let p = a * a + b * b;
        let q = -2.0 * a * c;

        //一个交点
        if (this.double_equals(d, r1 + r2)
            || this.double_equals(d, Math.abs(r1 - r2))) {
            //console.log("一个交点");
            insectInfo.insectType = 1;
            insectInfo.arg1 = x2 - x1;
            insectInfo.arg2 = y2 - y1;
            return insectInfo;
        }

        //两个交点
        let r = c * c - b * b;
        let cos_value1 = (Math.sqrt(q * q - 4.0 * p * r) - q) / p / 2.0;
        let cos_value2 = (-Math.sqrt(q * q - 4.0 * p * r) - q) / p / 2.0;
        let sin_value1 = Math.sqrt(1 - cos_value1 * cos_value1);
        let sin_value2 = Math.sqrt(1 - cos_value2 * cos_value2);
        let pt1 = { x: 0, y: 0 };
        let pt2 = { x: 0, y: 0 };
        pt1.x = r1 * cos_value1 + x1;
        pt1.y = r1 * sin_value1 + y1;
        pt2.x = r1 * cos_value2 + x1;
        pt2.y = r1 * sin_value2 + y1;


        if (!this.double_equals(this.distance_sqr(pt1.x, pt1.y, x2, y2),
            r2 * r2)) {
            pt1.y = y1 - r1 * sin_value1;
        }
        if (!this.double_equals(this.distance_sqr(pt2.x, pt2.y, x2, y2),
            r2 * r2)) {
            pt2.y = y1 - r1 * sin_value2;
        }
        if (this.double_equals(y1, y2)
            && this.double_equals(x1, x2)) {
            if (pt1.y > 0) {
                pt2.y = -pt2.y;
            }
            else {
                pt1.y = -pt1.y;
            }
        }

        /*  shp.graphics.lineStyle( 2, 0xff0000 );
            shp.graphics.moveTo( x1,y1 );
            shp.graphics.lineTo( pt1.x,pt1.y );
     
            shp.graphics.moveTo( x1,y1 );
            shp.graphics.lineTo( pt2.x,pt2.y );*/

        insectInfo.insectType = 2;


        let pt3 = MathUtils.getOnePointOnLine(pt1.x, pt1.y, pt2.x, pt2.y);


        let dir = egret.Point.create(0, 0);
        dir.x = pt3.x - x1;
        dir.y = pt3.y - y1;


        if (!MathUtils.Dot(dir.x, dir.y, x2 - x1, y2 - y1)) {
            dir.x = - dir.x;
            dir.y = - dir.y;
        }
        dir.normalize(1);
        /*     shp.graphics.lineStyle( 2, 0xff0000 );
            shp.graphics.moveTo( x1,y1 );
             shp.graphics.lineTo(x1+  dir.x*50,y1+dir.y*50 );
                shp.graphics.endFill();
             singleGame.ins.addChild(shp);*/


        insectInfo.arg1 = dir.x;
        insectInfo.arg2 = dir.y;

        //   console.log("第一个人的位置" + x1 + "|" + y1 + "移动半径" + r1 + "第二个人的位置" + x2 + "|" + y2 + "线长" + r2 + "相交类型" + insectInfo.insectType + "参数" + insectInfo.arg1 + "," + insectInfo.arg2);



        /*	var nextPointOne = MathUtils.calculateNextPointEx(x1,y1, dir.x, dir.y,r1,true );
        	
            var distance = (x2- nextPointOne.x) * (x2- nextPointOne.x)  + (y2 - nextPointOne.y) * (y2- nextPointOne.y);
            if(Math.sqrt(distance) >r2)
            {
                    console.log("矫正过后的距离" + Math.sqrt(distance));
            }
        */

        return insectInfo;
    }

    public static getFootfallPoint(x1: number, y1: number, x2: number, y2: number, x: number, y: number) {

        let a = (y1 - y2) / ((x1 - x2) == 0 ? 1 : x1 - x2);
        let b = y1 - a * y1;
        let m = x + a * y;
        let pt = { x: 0, y: 0 };
        pt.x = (m - a * b) / (a * a + 1);
        pt.y = (a * pt.x) + b;
        return pt;
    }

    public static getFootfallDistance(x1: number, y1: number, x2: number, y2: number, x: number, y: number) {
        let a = (y1 - y2) / ((x1 - x2) < 0.05 ? 0.05 : (x1 - x2));
        let b = y1 - a * y1;
        /// > 0 = ax +b -y;  
        return Math.abs(a * x + b - y / Math.sqrt(a * a + 1));
    }

    public static checkPointOnSegment(x1: number, y1: number, x2: number, y2: number, x: number, y: number): boolean {
        let max_x = x1 > x2 ? x1 : x2;
        let min_x = x1 < x2 ? x1 : x2;
        let max_y = y1 > y2 ? y1 : y2;
        let min_y = y1 < y2 ? y1 : y2;

        if (x >= min_x && x <= max_x && y >= min_y && y <= max_y)
            return true;

        return false;
    }




}